package org.ktjy.springbootsecurity.config;

import jakarta.annotation.Resource;
import org.ktjy.springbootsecurity.handle.MyAccessDeniedHandler;
import org.ktjy.springbootsecurity.service.UserDetailsServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.access.expression.WebExpressionAuthorizationManager;
import org.springframework.security.web.authentication.rememberme.JdbcTokenRepositoryImpl;
import org.springframework.security.web.authentication.rememberme.PersistentTokenRepository;

import javax.sql.DataSource;

import static org.springframework.security.config.Customizer.withDefaults;

@Configuration
@EnableWebSecurity
public class SecurityConfiger {
    @Autowired
    private MyAccessDeniedHandler myAccessDeniedHandler;
    @Resource
    private UserDetailsServiceImpl userDetailsService;
    @Resource
    private DataSource dataSource;
    @Bean
    public PersistentTokenRepository getpersistentTokenRepository(){
        JdbcTokenRepositoryImpl jdbcTokenRepository = new JdbcTokenRepositoryImpl();
        //设置数据源
        jdbcTokenRepository.setDataSource(dataSource);
        jdbcTokenRepository.setCreateTableOnStartup(true);
        return jdbcTokenRepository;
    }

    @Bean
    public PasswordEncoder getPw(){
        return new BCryptPasswordEncoder();
    }

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        //表单提交
        http.formLogin(formLoginSpec -> formLoginSpec
                        .loginPage("/toLogin")
                        //配置登录成功后跳转页面
                        .loginProcessingUrl("/doLogin")
                        .defaultSuccessUrl("/toMain")
                        //配置登录失败后跳转页面 
                        .failureUrl("/toError")
                        .permitAll());
        //授权认证
        http.authorizeHttpRequests((authz) -> authz
                .requestMatchers("/toLogin","/toError").permitAll()
                .requestMatchers("/css/**","/js/**","/images/**").permitAll()
//                .requestMatchers("/toMain1").hasRole("admin")
//                .requestMatchers("/toMain1").hasRole("abc")
//                .requestMatchers("/toMain1").access(new WebExpressionAuthorizationManager(
//                        "isAuthenticated() and hasIpAddress('192.168.0.6')"))
//                .requestMatchers("/toMain1").access(new WebExpressionAuthorizationManager(
//                                "isAuthenticated() and (hasIpAddress('192.168.0.6') or hasIpAddress('0:0:0:0:0:0:0:1'))"))
                .anyRequest().authenticated()
        );

        //异常处理
        http.exceptionHandling((ex) ->
                ex.accessDeniedHandler(myAccessDeniedHandler));

        //关闭csrf防火墙
        http.csrf(AbstractHttpConfigurer::disable);
        return http.build();
    }

}
